Guest = class('Guest'):include(Stateful)

function Guest:initialize(ip)
	self.tile_width = 16
	self.tile_height = 16
	self.ip = ip
	self.character_points = constants.character_points
	self.training_points = constants.training_points
	self.free_xp = 0
	self.total_xp = 0
	self.name = ""
	self.gender = ""
	self.unsafe = {}
	self.unsafe_skills = {}
	self.stats = {}
	self.stats.energy = 0
	self.stats.grit = 0
	self.stats.concentration = 0
	self.stats.might = 0
	self.stats.persistence = 0
	self.stats.coordination = 0
	self.stats.lithe = 0
	self.stats.understanding = 0
	self.stats.resolve = 0
	self.stats.kismet = 0
	self.stats.run = 0
	self.stats.jump = 0
	self.stats.light_melee = 0
	self.stats.heavy_melee = 0
	self.stats.light_ranged = 0
	self.stats.heavy_ranged = 0
	self.stats.akimbo = 0
	self.stats.stealth = 0
	self.stats.detect_stealth = 0
	self.stats.locksmithing = 0
	self.stats.tracking = 0
	self.stats.trapping = 0
	self.stats.melee_d = 0
	self.stats.ranged_d = 0
	self.stats.kidnapping = 0
	self.stats.interrogation = 0
	self.stats.escape = 0
	self.stats.tolerance = 0
	self.stats.elementalism = 0
	self.stats.chaos = 0
	self.stats.blessing = 0
	self.stats.summoning = 0
	self.stats.mentalism = 0
	self.stats.demolitions = 0
	self.stats.medicine = 0
	self.stats.mechanics = 0
	self.stats.cyber = 0
	self.stats.psychology = 0

	
end

function Guest:set_email(email)
	self.email = email
end

function Guest:set_pass(pass)
	self.pass = pass
end

function Guest:set_ip(ip)
	self.ip = ip
end

function Guest:set_peer(peer)
	self.peer = peer
	self:set_ip(tostring(peer))
end

function Guest:set_team(team)
	self.team = team
end

function Guest:set_position(x, y)
	print("setting " .. self.name .. " position to " .. x .. ", " .. y)
	self.x = x
	self.y = y
	self.peer:send("[setX]"..x)
	self.peer:send("[setY]"..y)
end

function Guest:get_position_string()
	if self.x and self.y then
		return "{ [\"x\"] = " .. self.x .. ", [\"y\"] = " .. self.y .. ",[\"ip\"] = " .. "\"" .. self.ip .."\"" .. "}"
	else
		return ""
	end
end

function Guest:get_position()
	return self.x, self.y
end

function Guest:get_email()
	return self.email
end

function Guest:get_pass()
	return self.pass
end

function Guest:get_ip()
	return self.ip
end

function Guest:set_stat(stat, value)
	self.stats[stat] = value
end

function Guest:pos_to_tiles()		
	local sy = self.y
	local sx = self.x
	self.last_x = self.x
	self.last_y = self.y
	print("converting " .. sx .. ", " .. sy .. " to tiles" )
	local loc = "nat"

	local js, je = 490, 3098

	

	if self.y <= js then
		loc = "nat"
	elseif self.y > js and self.y < je then
		sy = self.y - js - self.tile_height
		sx = self.x + self.tile_width
		loc = "jung"
	elseif self.y >= je then
		sy = self.y - je - self.tile_height
		sx = self.x 
		loc = "tech"
	end

	local rx, ry = math.floor(sx/self.tile_width), math.floor(sy/self.tile_height)

	
	
	print("result: " .. rx .. ", " .. ry .. " in " .. loc)
	return rx, ry, loc
end

function Guest:move(x, y, dt, ip)
	local sx, sy, loc = self:pos_to_tiles()

	self.moving = true

	
	
	if Guest:check_collision(sx, sy, x, y, loc) then
		self.x = self.x + (x*self.tile_width)--(x * (dt*self.stats.run))
		self.y = self.y + (y*self.tile_height)--(y * (dt*self.stats.run))
		self:set_position(self.x, self.y)
	end
	
end

function Guest:check_collision(x, y, dx, dy, loc)
	--print("collision ip .. " .. ip)
	print("moving " .. dx .. ", " .. dy .. " from " .. x .. ", " .. y)
	x, y = x+ dx, y+dy
	
	--local cc = love.thread.getChannel("collision_check")
	--local s = ip .. "," .. x .. "," .. y .. "," .. actual_x .. "," .. actual_y
	--cc:push(s)
	
	

	if loc == "nat" and y > 30  then
		print("transforming phantom row 31")
			loc = "jung"
			y = 0
			x = x + 1
	
	elseif loc == "jung" and y < 0 then
		loc = "nat"
		y = 30

	elseif loc == "jung" and y > 161 then
		loc = "tech"
		y = 1
	elseif loc == "tech" and y < -1 then
		loc = "jung"
		y = 161
		x = x + 1
	end	

	print("checking collision at ".. x .. ", " .. y .. " in " .. loc)

	if loc == "nat" then
		ss = love.thread.getChannel("nature_collision_data")
	elseif loc == "jung" then
		ss = love.thread.getChannel("jungle_collision_data")
	elseif loc == "tech" then
		ss = love.thread.getChannel("tech_collision_data")
	end

	local col = ss:peek()

	--print(table.tostring(col))

	--debug.debug()

	if col and col[server.w*y+x] and col[server.w*y+x] > 0 then
		print("collision found")
		return false		
	else
		print("collision not found")
		return true
	end
end

function Guest:send_guest_locations(gstring)
	self.peer:send("[guest_pos]"..gstring)

end

function Guest:add_unsafe_skill(name, level)
	self.unsafe_skills[name] = level
end

function Guest:validate_unsafe_skills()
	local tp_needed = 0
	for k, v in pairs(self.unsafe_skills) do
		if v == "train" then
			tp_needed = tp_needed + skill_cost_list[k][v]
		elseif v == "spec" then
			tp_needed = tp_needed + skill_cost_list[k]["train"] + skill_cost_list[k]["spec"]
		end
	end

	if tp_needed <= constants.training_points then
		self.training_points = constants.training_points - tp_needed
		for k, v in pairs(self.unsafe_skills) do
			if v == "train" then
				self.stats[k] = self.stats[k] + 10
			elseif v == "spec" then
				self.stats[k] = self.stats[k] + 25
			end
		end
		self:save()
		return true
	end
	
end

function Guest:add_unsafe_stat(stat, value)
	print("adding unsafe stat ".. stat .. " with " .. value)
	
	self.unsafe[stat] = value
	print(#self.unsafe)
	print(self.unsafe[stat])
end

function Guest:validate_unsafe_stats()
	print("validating stats", #self.unsafe)
	local added_cp = 0	
	for k, v in pairs(self.unsafe) do
		print(k, v)
		if k ~= "name" and k ~= "gender" then
			added_cp = added_cp + tonumber(v)
		end
	end
	print(added_cp .. " used cp")

	if added_cp == constants.character_points then
		for k, v in pairs(self.unsafe) do
			if k ~= "name" and k ~= "gender" then
				self:set_stat(k, tonumber(v))
			end
		end
	end
	self.character_points = 0
	self.name = self.unsafe.name
	self.gender = self.unsafe.gender
	self:compute_skills()
	self:save()
end

function Guest:compute_skills()
	print("computing skills")
	for k, v in pairs(self.stats) do
		print(k, v)
		self.stats[k] = math.floor(stat_chart[k]["compute"](self))
	end
end

function Guest:connected(peer, isNew, map_string, extra_tiles)	
	self:set_peer(peer)
	self.peer:send("guest_authed")
	self.peer:send("[training_points]"..self.training_points)
	self.peer:send("[character_points]"..self.character_points)
	self.peer:send("[setIP]"..tostring(self.peer))

	if not isNew then		
		self.peer:send("[name]"..self.name)
		self.peer:send("[gender]".. self.gender)
		self.peer:send("[energy]"..self.stats.energy)
		self.peer:send("[grit]".. self.stats.grit)
		self.peer:send("[concentration]"..self.stats.concentration)
		self.peer:send("[might]"..self.stats.might)
		self.peer:send("[persistence]"..self.stats.persistence)
		self.peer:send("[coordination]"..self.stats.coordination)
		self.peer:send("[lithe]"..self.stats.lithe)
		self.peer:send("[understanding]"..self.stats.understanding)
		self.peer:send("[resolve]"..self.stats.resolve)
		self.peer:send("[kismet]"..self.stats.kismet)
		self.peer:send("[run]"..self.stats.run)
		self.peer:send("[jump]"..self.stats.jump)
		self.peer:send("[light_melee]"..self.stats.light_melee)
		self.peer:send("[heavy_melee]"..self.stats.heavy_melee)
		self.peer:send("[light_ranged]"..self.stats.light_ranged)
		self.peer:send("[heavy_ranged]"..self.stats.heavy_ranged)
		self.peer:send("[akimbo]"..self.stats.akimbo)
		self.peer:send("[stealth]"..self.stats.stealth)
		self.peer:send("[detect_stealth]"..self.stats.detect_stealth)
		self.peer:send("[locksmithing]"..self.stats.locksmithing)
		self.peer:send("[tracking]"..self.stats.tracking)
		self.peer:send("[trapping]"..self.stats.trapping)
		self.peer:send("[melee_d]"..self.stats.melee_d)
		self.peer:send("[ranged_d]"..self.stats.ranged_d)
		self.peer:send("[kidnapping]"..self.stats.kidnapping)
		self.peer:send("[interrogation]"..self.stats.interrogation)
		self.peer:send("[escape]"..self.stats.escape)
		self.peer:send("[tolerance]"..self.stats.tolerance)
		self.peer:send("[elementalism]"..self.stats.elementalism)
		self.peer:send("[chaos]"..self.stats.chaos)
		self.peer:send("[blessing]"..self.stats.blessing)
		self.peer:send("[summoning]"..self.stats.summoning)
		self.peer:send("[mentalism]"..self.stats.mentalism)
		self.peer:send("[demolitions]"..self.stats.demolitions)
		self.peer:send("[medicine]"..self.stats.medicine)
		self.peer:send("[mechanics]"..self.stats.mechanics)
		self.peer:send("[cyber]"..self.stats.cyber)
		self.peer:send("[psychology]"..self.stats.psychology)		
		self:save()
		self.peer:send("[enter_game]")
	else		
		self.peer:send("[make_new_char]")
	end

	self.peer:send("[current_map]" .. map_string)
	self.peer:send("[extra_tiles]".. extra_tiles)
end




function Guest:save()	
	
	local s = [[
	local g = {}
	g.ip = "]] .. tostring(self.ip) .. [[";
	g.email = "]] .. self.email .. [[";
	g.pass = "]] .. self.pass .. [[";
	g.character_points = ]] .. self.character_points .. [[;
	g.training_points = ]] .. self.training_points .. [[;
	g.free_xp = ]] .. self.free_xp .. [[;
	g.total_xp = ]] .. self.total_xp .. [[;
	g.name = "]] .. self.name .. [[";
	g.gender = "]] .. self.gender .. [[";
	g.stats = {};
	g.stats.energy = ]] .. self.stats.energy .. [[;
	g.stats.grit = ]] .. self.stats.grit .. [[;
	g.stats.concentration = ]] .. self.stats.concentration  .. [[;
	g.stats.might = ]] .. self.stats.might .. [[;
	g.stats.persistence = ]] .. self.stats.persistence .. [[;
	g.stats.coordination = ]] .. self.stats.coordination .. [[;
	g.stats.lithe = ]] .. self.stats.lithe .. [[;
	g.stats.understanding = ]] .. self.stats.understanding .. [[;
	g.stats.resolve = ]] .. self.stats.resolve .. [[;
	g.stats.kismet = ]] .. self.stats.kismet .. [[;
	g.stats.run = ]] .. self.stats.run .. [[;
	g.stats.jump = ]] .. self.stats.jump .. [[;
	g.stats.light_melee = ]] .. self.stats.light_melee .. [[;
	g.stats.heavy_melee = ]] .. self.stats.heavy_melee .. [[;
	g.stats.light_ranged = ]] .. self.stats.light_ranged .. [[;
	g.stats.heavy_ranged = ]] .. self.stats.heavy_ranged .. [[;
	g.stats.akimbo = ]] .. self.stats.akimbo .. [[;
	g.stats.stealth = ]] .. self.stats.stealth .. [[;
	g.stats.detect_stealth = ]] ..self.stats.detect_stealth .. [[;
	g.stats.locksmithing = ]] .. self.stats.locksmithing .. [[;
	g.stats.tracking = ]] .. self.stats.tracking .. [[;
	g.stats.trapping = ]] .. self.stats.trapping .. [[;
	g.stats.melee_d = ]] .. self.stats.melee_d .. [[;
	g.stats.ranged_d = ]] .. self.stats.ranged_d .. [[;
	g.stats.kidnapping = ]] .. self.stats.kidnapping .. [[;
	g.stats.interrogation = ]] .. self.stats.interrogation .. [[;
	g.stats.escape = ]] .. self.stats.escape .. [[;
	g.stats.tolerance = ]] .. self.stats.tolerance .. [[;
	g.stats.elementalism = ]] .. self.stats.elementalism .. [[;
	g.stats.chaos = ]].. self.stats.chaos .. [[;
	g.stats.blessing = ]] .. self.stats.blessing .. [[;
	g.stats.summoning = ]] .. self.stats.summoning .. [[;
	g.stats.mentalism = ]] .. self.stats.mentalism .. [[;
	g.stats.demolitions = ]] .. self.stats.demolitions .. [[;
	g.stats.medicine = ]] .. self.stats.medicine .. [[;
	g.stats.mechanics = ]] .. self.stats.mechanics .. [[;
	g.stats.cyber = ]] .. self.stats.cyber .. [[;
	g.stats.psychology = ]] ..self.stats.psychology .. [[;
	return g
	]]

	love.filesystem.write(self.email, s)
end